package cn.wolfcode.service.impl;

import cn.wolfcode.common.exception.BusinessException;
import cn.wolfcode.domain.AccountLog;
import cn.wolfcode.domain.AccountTransaction;
import cn.wolfcode.domain.OperateIntergralVo;
import cn.wolfcode.mapper.AccountLogMapper;
import cn.wolfcode.mapper.AccountTransactionMapper;
import cn.wolfcode.mapper.UsableIntegralMapper;
import cn.wolfcode.service.IUsableIntegralService;
import cn.wolfcode.web.msg.IntergralCodeMsg;
import com.alibaba.fastjson.JSON;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;


@Service
@Transactional
@Slf4j
public class UsableIntegralServiceImpl implements IUsableIntegralService {
    @Autowired
    private UsableIntegralMapper usableIntegralMapper;
    @Autowired
    private AccountTransactionMapper accountTransactionMapper;
    @Autowired
    private AccountLogMapper accountLogMapper;


    @Override
    public void decrIntergralTry(OperateIntergralVo operateIntergralVo, BusinessActionContext context) {
        log.info("进入try方法");
        //插入事务表
        AccountTransaction accountTransaction = new AccountTransaction();
        accountTransaction.setActionId(context.getBranchId() + "");
        accountTransaction.setAmount(operateIntergralVo.getValue());
        accountTransaction.setGmtCreated(new Date());
        accountTransaction.setGmtModified(new Date());
        accountTransaction.setState(AccountTransaction.STATE_TRY);
        accountTransaction.setTxId(context.getXid());
        accountTransaction.setType(AccountTransaction.DCER_TRY + "");
        accountTransaction.setUserId(operateIntergralVo.getUserId());
        accountTransactionMapper.insert(accountTransaction);
        //执行积分冻结
        int i = usableIntegralMapper.freezeIntergral(operateIntergralVo.getUserId(), operateIntergralVo.getValue());
        if (i == 0) {
            log.info("积分冻结失败");
        }

    }

    @Override
    public void decrIntergralCommit(BusinessActionContext context) {
        log.info("进入confirm方法");
        //查询事务是否为空
        AccountTransaction accountTransaction = accountTransactionMapper.get(context.getXid(), context.getBranchId() + "");
        if (accountTransaction == null) {
            log.info("异常处理");
        }
        if (accountTransaction.getState().equals(AccountTransaction.STATE_TRY)) {
            //扣除解冻的积分
            Object operateIntergralVo = context.getActionContext("operateIntergralVo");
            OperateIntergralVo operateIntergralVo1 = JSON.parseObject(operateIntergralVo.toString(), OperateIntergralVo.class);
            int i = usableIntegralMapper.commitChange(operateIntergralVo1.getUserId(), operateIntergralVo1.getValue());
            if (i == 0) {
                log.info("积分解冻失败");
            }
            //修改状态为已提交
            accountTransactionMapper.updateAccountTransactionState(context.getXid(), context.getBranchId() + "", AccountTransaction.STATE_COMMIT, AccountTransaction.STATE_TRY);

        } else if (accountTransaction.getState().equals(AccountTransaction.STATE_COMMIT)) {
            log.info("幂等异常");
        } else {
            log.info("异常处理");
        }

    }

    @Override
    public void decrIntergralRollback(BusinessActionContext context) {
        log.info("进入cancel方法");
        Object operateIntergralVo = context.getActionContext("operateIntergralVo");
        OperateIntergralVo operateIntergralVo1 = JSON.parseObject(operateIntergralVo.toString(), OperateIntergralVo.class);

        //进行积分解冻
        AccountTransaction accountTransaction = accountTransactionMapper.get(context.getXid(), context.getBranchId() + "");
        if (accountTransaction == null) {
            AccountTransaction accountTransaction1 = new AccountTransaction();
            accountTransaction1.setActionId(context.getBranchId() + "");
            accountTransaction1.setAmount(operateIntergralVo1.getValue());
            accountTransaction1.setGmtCreated(new Date());
            accountTransaction1.setGmtModified(new Date());
            accountTransaction1.setState(AccountTransaction.STATE_CANCEL);
            accountTransaction1.setTxId(context.getXid());
            accountTransaction1.setType(AccountTransaction.DCER_TRY + "");
            accountTransaction1.setUserId(operateIntergralVo1.getUserId());
            accountTransactionMapper.insert(accountTransaction1);
        }
        if (accountTransaction.getState().equals(AccountTransaction.STATE_TRY)) {
            //执行积分返回
            usableIntegralMapper.unFreezeIntergral(operateIntergralVo1.getUserId(), operateIntergralVo1.getValue());
        } else if (accountTransaction.getState().equals(AccountTransaction.STATE_CANCEL)) {
            log.info("幂等性");
        } else {
            log.info("异常处理");
        }

    }


    @Override
    public void decrIntergral(OperateIntergralVo operateIntergralVo) {
        //插入积分支付流水
        AccountLog accountLog = new AccountLog();
        accountLog.setAmount(operateIntergralVo.getValue());
        accountLog.setGmtTime(new Date());
        accountLog.setInfo(operateIntergralVo.getInfo());
        accountLog.setPkValue(operateIntergralVo.getPk());
        accountLog.setType(AccountLog.TYPE_DECR);
        accountLogMapper.insert(accountLog);
        //减少用户积分
        int count = usableIntegralMapper.decrIntergral(operateIntergralVo.getUserId(), operateIntergralVo.getValue());
        if (count == 0) {
            throw new BusinessException(IntergralCodeMsg.INTERGRAL_NOT_ENOUGH);
        }
    }

    @Transactional
    @Override
    public void inseIntergral(OperateIntergralVo operateIntergralVo) {

        AccountLog accountLog = new AccountLog();
        accountLog.setAmount(operateIntergralVo.getValue());
        accountLog.setGmtTime(new Date());
        accountLog.setInfo(operateIntergralVo.getInfo());
        accountLog.setPkValue(operateIntergralVo.getPk());
        accountLog.setType(AccountLog.TYPE_INCR);
        accountLogMapper.insert(accountLog);
    }
}
